/**
 * 
 */
package edu.gtcfla.km.appmodules.service.impl;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.vsg.biz.BusinessOperationException;
import org.vsg.common.model.algstrategy.GenTreeModelBuilder;
import org.vsg.common.model.json.TreeNode;
import org.vsg.common.page.AbstractPage;
import org.vsg.common.page.PageContentConverter;
import org.vsg.common.page.PageConverterTemplate;
import org.vsg.search.api.criterion.PaginationCriteria;
import org.vsg.search.api.page.PaginationException;

import edu.gtcfla.km.Category;
import edu.gtcfla.km.Knowledge;
import edu.gtcfla.km.UploadFile;
import edu.gtcfla.km.UserGroup;
import edu.gtcfla.km.UserGroupPermission;
import edu.gtcfla.km.UserPermission;
import edu.gtcfla.km.appmodules.service.KnowledgeService;
import edu.gtcfla.km.appmodules.vo.DefaultPage;
import edu.gtcfla.km.appmodules.vo.KnowledgeFormVO;
import edu.gtcfla.km.appmodules.vo.KnowledgeListViewVO;
import edu.gtcfla.km.model.KnowledgeD;
import edu.gtcfla.km.repositories.CategoryRepo;
import edu.gtcfla.km.repositories.KnowledgeRepo;
import edu.gtcfla.km.repositories.UploadFileRepo;
import edu.gtcfla.km.repositories.UserGroupPermissionRepo;
import edu.gtcfla.km.repositories.UserGroupRepo;
import edu.gtcfla.km.repositories.UserPermissionRepo;
import edu.gtcfla.km.security.api.SubjectManager;

/**
 * @author vison
 *
 */
public class KnowledgeServiceI implements KnowledgeService {

	@Autowired(required=false)
	private KnowledgeRepo<Knowledge, String> knowledgeRepo;
	
	@Autowired(required=false)
	private CategoryRepo<Category, String> categoryRepo;
	
	@Autowired(required=false)	
	private UserPermissionRepo<UserPermission,Serializable> userPermissionRepo;
	

	@Autowired(required=false)	
	private UserGroupPermissionRepo<UserGroupPermission , String> usergroupPermRepo;
	
	@Autowired(required=false)	
	private UserGroupRepo<UserGroup , String> userGroupRepo;	
	
	@Autowired(required=false)	
	private UploadFileRepo<UploadFile ,String> uploadFileRepo;
	
	
	@Autowired(required = false)
	private SubjectManager subjectManager;		
	
	@Override
	public Page<KnowledgeListViewVO> pageAvailableAllList(PaginationCriteria criteria)
			throws BusinessOperationException, PaginationException {
		// --- all sub version ---
		String accountId = subjectManager.getCurrentAccountId();

		// --- get current group current permission --
		UserGroup userGroup = userGroupRepo.findFirstOneByUserId(accountId);		
		
		// --- get current user group from account ---
		
		// --- usergroup perms
		Map<String, UserGroupPermission>  usergroupPerms = new LinkedHashMap<String , UserGroupPermission>();
		if (userGroup != null) {
			usergroupPerms = this.usergroupPermRepo.findUserGroupPermissionForCategories(userGroup.getId());
		}
		
		// --- get user permission suppport ---
		Map<String, UserPermission>  supportedUserPermMap =  userPermissionRepo.findUserPermissionForCategories( accountId );
		
		// --- get current user role  ---
		Serializable categoryId =  criteria.getValue("categoryId");
		
		UserPermission supportUserPerm = supportedUserPermMap.get( categoryId );
		UserGroupPermission supportUserGroupPerm = usergroupPerms.get( categoryId );
		
		// --- get the user perm ---
		if (supportUserPerm == null  && supportUserGroupPerm == null) {
			// --- return empty ---
			Page<KnowledgeListViewVO> target =  new DefaultPage<KnowledgeListViewVO>();
			return target;
		}

		
		Map<String, Category>  categoryMap =  categoryRepo.findAllMap() ;

		// --- find the submenu ---
		GenTreeModelBuilder genTreeBuilder = new GenTreeModelBuilder( categoryMap );
		genTreeBuilder.generate();
		
		Map<String , TreeNode> treeMap = genTreeBuilder.getResultMap();
		
		TreeNode currentCate = treeMap.get( categoryId.toString() );

		// --- get all category ---
		Set<String> allCateIds = new LinkedHashSet<String>();
		findAllCategoryIds(currentCate , allCateIds);
		
		// --- add condition ---
		String userGroupId = null;
		if (userGroup != null) {
			userGroupId = userGroup.getId();
		}
		
		// --- get the currnet all content ---
		Page<Knowledge>  pageKnowledge = 
				knowledgeRepo.pageKnowledgeByCurrentUser( criteria , allCateIds ,  accountId , userGroupId); 
		

		
		PageContentConverter<KnowledgeListViewVO , Knowledge> converter = new PageContentConverter<KnowledgeListViewVO , Knowledge>() {

			@Override
			public KnowledgeListViewVO convert(Knowledge input) {
				KnowledgeListViewVO item = new KnowledgeListViewVO(input);
				
				if (item.getKeywords() == null) {
					item.setKeywords("");
				}
				if (item.getContent() == null) {
					item.setContent("");
				}
				
				return item;
			}
		};
		
		PageConverterTemplate<KnowledgeListViewVO , Knowledge> pageTemplate = 
				new PageConverterTemplate<KnowledgeListViewVO , Knowledge>( pageKnowledge );
		
		Page<KnowledgeListViewVO> target = pageTemplate.convertContent(converter);
		AbstractPage cpi = (AbstractPage)target;
		cpi.setTotalRecord( (int) pageKnowledge.getTotalElements() );
		
		
		return target;
	}
	
	private void findAllCategoryIds(TreeNode treeNode , Set<String> allIds) {
		allIds.add( treeNode.getId() );
		
		Collection<TreeNode> coll = treeNode.getChildren();
		if ( coll != null && !coll.isEmpty() ) {
			for (TreeNode subTreeNode : coll) {
				findAllCategoryIds(subTreeNode , allIds);
			}
		}

		
	}
	

	@Override
	public void addKnowledge(KnowledgeFormVO infoForm)
			throws BusinessOperationException {

		// --- all sub version ---
		String accountId = subjectManager.getCurrentAccountId();		
		
		UserGroup userGroup = userGroupRepo.findFirstOneByUserId(accountId);		
		
		Category category = categoryRepo.findOne(infoForm.getCategoryId());
		

		Knowledge knowledge = new KnowledgeD();
		knowledge.setTitle(infoForm.getTitle());
		knowledge.setKeywords(infoForm.getKeywords());
		knowledge.setContent(infoForm.getContent());
		knowledge.setReleasedDate(new Date());
		knowledge.setShared( infoForm.getShared() );
		
		// --- get current user id and org id ---
		knowledge.setReleasedUserId(accountId);
		if (userGroup != null) {
			knowledge.setUserGroupId( userGroup.getId() );
		}
		
		knowledge.setCategory(category);
		knowledgeRepo.save(knowledge);

	}

	@Override
	public KnowledgeFormVO getSingleKnowledgeDetail(String docId)
			throws BusinessOperationException {
		Knowledge knowledge = knowledgeRepo.findOne(docId);
		
		KnowledgeFormVO form = new KnowledgeFormVO();
		if(knowledge!=null){
			form.setId(docId);
			form.setContent(knowledge.getContent());
			form.setKeywords(knowledge.getKeywords());
			form.setTitle(knowledge.getTitle());
			//form.setType(knowledge.get);
			
		}
		return form;
	}

	@Override
	public void updateKnowledge(KnowledgeFormVO infoForm)
			throws BusinessOperationException {
		Knowledge knowledge = knowledgeRepo.findOne(infoForm.getId());
		System.out.println("infoForm.getCategoryId()>>>>  " + infoForm.getCategoryId());
		Category category = categoryRepo.findOne(infoForm.getCategoryId());
		System.out.println("category>>>>  " + category);
		
		//knowledge.setId("123");
		knowledge.setTitle(infoForm.getTitle());
		knowledge.setKeywords(infoForm.getKeywords());
		//knowledge.setType("type");
		knowledge.setContent(infoForm.getContent());
		knowledge.setReleasedUserId("1");
		knowledge.setCategory(category);
		knowledgeRepo.update(knowledge);
		
		System.out.println("update success");
		
	}

	@Override
	public void deleteAllKnowledge(String[] moreKnowledgeIds)
			throws BusinessOperationException {
		for(String id : moreKnowledgeIds){
			//Knowledge knowledge = knowledgeRepo.findOne(id);
			Knowledge knowledge = new KnowledgeD();
			knowledge.setId(id);
			System.out.println("deleteAllKnowledge  >>  knowledge >>  " + knowledge + "  id >> " + id);
			//if(knowledge!=null){
				knowledgeRepo.deleteDirectly(knowledge);
			//}
		}
		
		
	}

	@Override
	public void bindAttachments(List<String> attIds, String docId)
			throws BusinessOperationException {
		
		Knowledge  knowledge = knowledgeRepo.findOne( docId );
		
		Map<String , UploadFile> uploadFileMap = uploadFileRepo.findAllMapByIds( attIds );
		
		for (UploadFile uf : uploadFileMap.values() ) {
			uploadFileRepo.bindingAttacthmentToDoc(uf , knowledge);
			
		}
		

	}

	@Override
	public Set<KnowledgeListViewVO> listAvailableByCategoryId(String categoryId)
			throws BusinessOperationException {
		
		Set<Knowledge> allKnowLedge =  knowledgeRepo.listKnowledgeByCategoryId(categoryId);

		Set<KnowledgeListViewVO> allListView = new LinkedHashSet<KnowledgeListViewVO>();
		
		
		for (Knowledge knowledge : allKnowLedge) {
			KnowledgeListViewVO item = new KnowledgeListViewVO(knowledge);
			
			if (item.getKeywords() == null) {
				item.setKeywords("");
			}
			if (item.getContent() == null) {
				item.setContent("");
			}
			
			allListView.add( item ); 
					
		}
		
		return allListView;
	}

	

	
}
